package cn.gcjxsc.service.integral;

import cn.gcjxsc.consts.CheckStatus;
import cn.gcjxsc.data.query.salesman.SalesmanQuery;
import cn.gcjxsc.data.vo.salesman.SalesmanVo;
import cn.gcjxsc.entity.member.Member;
import cn.gcjxsc.entity.merchant.CheckApplyInfoRecord;
import cn.gcjxsc.entity.merchant.Store;
import cn.gcjxsc.entity.salesman.ApplyInfo;
import cn.gcjxsc.entity.salesman.Salesman;
import cn.gcjxsc.form.ApplyInfoForm;
import cn.gcjxsc.repository.merchant.CheckApplyInfoRecordRepository;
import cn.gcjxsc.repository.salesaman.ApplyInfoRepository;
import cn.gcjxsc.repository.salesaman.SalesmanRepository;
import cn.gcjxsc.repository.specs.SalesmanSpec;
import cn.gcjxsc.service.merchant.StoreService;
import com.zgxl.common.util.DateTimeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 业务员业务类
 *
 * @author pumbaa
 * @version 1.0
 * @since 1.0
 */
@Service
public class SalesmanService {
    @Autowired
    private SalesmanRepository salesmanRepository;
    @Autowired
    private ApplyInfoRepository applyInfoRepository;
    @Autowired
    private CheckApplyInfoRecordRepository checkApplyInfoRecordRepository;
    @Autowired
    private StoreService storeService;


    public Salesman findByStoreId(Integer storeId, Integer memberId) {
        return salesmanRepository.findByStoreIdAndMemberIdAndStatus(storeId, memberId, 1);
    }

    /**
     * 查询店铺所有的业务员
     *
     * @param storeId 店铺id
     * @return 返回业务员列表
     */
    public List<Salesman> queryStoreSalesmans(Integer storeId) {
        Salesman salesman = new Salesman();
        salesman.setStoreId(storeId);
        Example<Salesman> example = Example.of(salesman);
        return salesmanRepository.findAll(example);
    }

    /**
     * 查询指定店铺的业务员数量
     *
     * @param storeId 店铺id
     * @return 返回业务员的数量, 如果没有, 返回0
     */
    public long queryStoreSalesmanCount(Integer storeId) {
        return salesmanRepository.countByStoreIdAndStatus(storeId, 1);
    }

    /**
     * 同意商户邀请
     * @param member 会员信息
     * @param store 店铺信息
     * @return
     */
    @Transactional
    public ApplyInfo agreeInvitation(Member member, Store store){
        ApplyInfo info = new ApplyInfo();
        info.setCreated(DateTimeUtil.getTimestamp());
        info.setDoneTime(0L);
        info.setMemberId(member.getId());
        info.setName(member.getRealName());
        info.setMobile(member.getMobile());
        info.setStatus(CheckStatus.WAIT);
        info.setRemark("");
        info.setStoreId(store.getId());
        return applyInfoRepository.save(info);
    }

    /**
     * 提交业务员申请
     *
     * @param form 申请信息
     */
    @Transactional
    public ApplyInfo applyForSalesman(ApplyInfoForm form) {
        ApplyInfo info = new ApplyInfo();
        info.setCreated(DateTimeUtil.getTimestamp());
        info.setDoneTime(0L);
        info.setMemberId(form.getMemberId());
        info.setName(form.getName());
        info.setMobile(form.getMobile());
        info.setStatus(CheckStatus.WAIT);
        info.setRemark("");
        info.setStoreId(form.getStoreId());
        return applyInfoRepository.save(info);
    }

    /**
     * 审核业务员申请.如果通过审核,则同步生成一个业务员信息
     *
     * @param info    申请信息
     * @param handler 处理人
     * @param status  状态
     * @param remark  备注信息
     */
    @Transactional
    public void checkApplyInfo(ApplyInfo info, String handler, CheckStatus status, String remark) {
        long now = DateTimeUtil.getTimestamp();
        info.setStatus(status);
        info.setDoneTime(now);
        if (status == CheckStatus.PASSED) {
            //审核通过,添加业务员信息
            Salesman salesman = new Salesman();
            salesman.setMemberId(info.getMemberId());
            salesman.setStoreId(info.getStoreId());
            salesman.setName(info.getName());
            salesman.setMobile(info.getMobile());
            salesman.setRatio(new BigDecimal(0));
            salesman.setCreated(now);
            salesmanRepository.save(salesman);
        }
        CheckApplyInfoRecord record = new CheckApplyInfoRecord();
        record.setApplyInfo(info);
        record.setCreated(now);
        record.setStoreId(info.getStoreId());
        record.setUsername(handler);
        record.setRemark(remark);
        checkApplyInfoRecordRepository.save(record);
        applyInfoRepository.save(info);
    }

    /**
     * 查询指定id的申请信息
     *
     * @param id 申请记录id
     * @return
     */
    public ApplyInfo findApplyInfoById(Integer id) {
        return applyInfoRepository.findOne(id);
    }

    /**
     * 查询指定业务员已绑定的店铺数量
     *
     * @param mid 会员id
     * @return
     */
    public long queryStoresForMember(Integer mid) {
        return salesmanRepository.countByMemberIdAndStatus(mid, 1);
    }

    /**
     * 查询会员是否为指定店铺的业务员
     *
     * @param mid     会员id
     * @param storeId 店铺id
     * @return 如果是返回true, 否则返回false
     */
    public boolean isStoreSalesman(Integer mid, Integer storeId) {
        return salesmanRepository.countByMemberIdAndStoreIdAndStatus(mid, storeId, 1) > 0;
    }

    /**
     * 设置业务员的收益比例
     *
     * @param salesman 业务员
     * @param ratio    比例
     * @return
     */
    @Transactional
    public int updateSalesmanRatio(Salesman salesman, BigDecimal ratio) {
        return salesmanRepository.setRatio(salesman.getId(), ratio);
    }

    /**
     * 解除业务员绑定.并删除申请信息.
     *
     * @param salesman 业务员信息
     */
    @Transactional
    public void unbindSalesman(Salesman salesman) {
        ApplyInfo applyInfo = applyInfoRepository.findByMemberIdAndStoreIdAndStatus(salesman.getMemberId(), salesman.getStoreId(), CheckStatus.PASSED);
        salesmanRepository.save(salesman);
        if (null != applyInfo) {
            applyInfoRepository.delete(applyInfo);
        }
    }

    /**
     * 根据id查询业务员
     *
     * @param id 业务员id
     * @return
     */
    public Salesman findById(Integer id) {
        return salesmanRepository.findOne(id);
    }

    /**
     * 查询指定会员的所有业务员信息
     *
     * @param memberId 会员id
     * @return
     */
    public List<Salesman> findListByMember(Integer memberId) {
        Salesman salesman = new Salesman();
        salesman.setMemberId(memberId);
        salesman.setStatus(1);
        Example<Salesman> example = Example.of(salesman);
        return salesmanRepository.findAll(example);
    }

    /**
     * 查询业务员列表
     *
     * @param filter   过滤条件
     * @param page     当前页
     * @param pageSize 最大记录数
     * @return
     */
    public Page<Salesman> queryList(SalesmanQuery filter, int page, int pageSize) {
        filter.format();
        Pageable pageRequest = new PageRequest(page - 1, pageSize, new Sort(Sort.Direction.DESC, "created"));
        return salesmanRepository.findAll(SalesmanSpec.buildSalesmanFilter(filter), pageRequest);
    }

    /**
     * 将实体转换成vo
     * @param salesman 业务员信息
     * @return
     */
    public SalesmanVo convert(Salesman salesman){
        SalesmanVo vo = new SalesmanVo();
        BeanUtils.copyProperties(salesman, vo);
        return vo;
    }

    /**
     * 数据转换
     * @param salesmanList
     * @return
     */
    public List<SalesmanVo> convertList(List<Salesman> salesmanList){
            List<Integer> storeIds = new ArrayList<>();
            for (Salesman salesman : salesmanList) {
                storeIds.add(salesman.getStoreId());
            }
            List<Store> stores = storeService.findByIds(storeIds);
            Map<Integer, Store> storeMap = new HashMap<>();
            for (Store store : stores) {
                storeMap.put(store.getId(), store);
            }
            List<SalesmanVo> voList = new ArrayList<>();
            for (Salesman salesman : salesmanList) {
                Store store = storeMap.get(salesman.getStoreId());
                SalesmanVo vo = convert(salesman);
                vo.setStoreName(store.getName());
                voList.add(vo);
            }
            return voList;
    }

    @Transactional
    public Salesman saveOrUpdate(Salesman salesman) {
        return salesmanRepository.save(salesman);
    }
}
